import {
  computed,
  nextTick,
  onMounted,
  reactive,
  ref,
  watch,
  type Ref,
} from "vue";
import type { SelectProps, SelectState, SelectOptionProxy } from "./types";

/**
 * Select 组件的核心逻辑
 */
export function useSelect(
  props: Ref<SelectProps>,
  emit: (event: string, ...args: any[]) => void
) {
  // 状态管理
  const state = reactive<SelectState>({
    inputValue: "",
    options: new Map(),
    cachedOptions: new Map(),
    selected: [],
    selectedLabel: "",
    hoveringIndex: -1,
    inputHovering: false,
    expanded: false,
  });

  // DOM refs
  const selectRef = ref<HTMLElement | null>(null);
  const selectTriggerRef = ref<HTMLElement | null>(null);
  const selectDropdownRef = ref<HTMLElement | null>(null);
  const filterInputRef = ref<HTMLInputElement | null>(null);

  // 选项数组（用于渲染）
  const optionsArray = computed(() => {
    return Array.from(state.options.values());
  });

  // 过滤后的选项
  const filteredOptions = computed(() => {
    if (!props.value.filterable || !state.inputValue) {
      return optionsArray.value.filter((opt) => opt.visible !== false);
    }
    const query = state.inputValue.toLowerCase();
    return optionsArray.value.filter((opt) => {
      if (opt.visible === false) return false;
      return opt.currentLabel.toLowerCase().includes(query);
    });
  });

  // 设置选中项
  const setSelected = () => {
    if (props.value.multiple) {
      const modelValue = Array.isArray(props.value.modelValue)
        ? props.value.modelValue
        : [];
      state.selected = modelValue
        .map((val) => {
          const option = state.cachedOptions.get(val);
          if (option) {
            return {
              ...option,
              itemSelected: true,
            };
          }
          // 如果没有找到缓存的选项，创建一个
          const optionFromProps = props.value.options?.find(
            (opt) => opt.value === val
          );
          if (optionFromProps) {
            return {
              value: val,
              label: optionFromProps.label,
              currentLabel: optionFromProps.label,
              disabled: optionFromProps.disabled || false,
              visible: true,
              hover: false,
              itemSelected: true,
              isDisabled: optionFromProps.disabled || false,
              selectOptionClick: () => {},
            };
          }
          return null;
        })
        .filter(Boolean) as SelectOptionProxy[];
      state.selectedLabel = "";
    } else {
      const modelValue = props.value.modelValue;
      if (modelValue != null && modelValue !== "") {
        const option = state.cachedOptions.get(modelValue);
        if (option) {
          state.selected = [
            {
              ...option,
              itemSelected: true,
            },
          ];
          state.selectedLabel = option.currentLabel;
        } else {
          // 从 props.options 中查找
          const optionFromProps = props.value.options?.find(
            (opt) => opt.value === modelValue
          );
          if (optionFromProps) {
            state.selected = [
              {
                value: modelValue,
                label: optionFromProps.label,
                currentLabel: optionFromProps.label,
                disabled: optionFromProps.disabled || false,
                visible: true,
                hover: false,
                itemSelected: true,
                isDisabled: optionFromProps.disabled || false,
                selectOptionClick: () => {},
              },
            ];
            state.selectedLabel = optionFromProps.label;
          } else {
            state.selected = [];
            state.selectedLabel = String(modelValue);
          }
        }
      } else {
        state.selected = [];
        state.selectedLabel = "";
      }
    }
  };

  // 注册选项
  const onOptionCreate = (vm: SelectOptionProxy) => {
    state.options.set(vm.value, vm);
    state.cachedOptions.set(vm.value, vm);
    // 更新选中状态
    nextTick(() => {
      setSelected();
    });
  };

  // 销毁选项
  const onOptionDestroy = (key: any, vm: SelectOptionProxy) => {
    if (state.options.get(key) === vm) {
      state.options.delete(key);
    }
  };

  // 处理选项选择
  const handleOptionSelect = (option: SelectOptionProxy) => {
    if (props.value.multiple) {
      const currentValue = Array.isArray(props.value.modelValue)
        ? [...props.value.modelValue]
        : [];
      const index = currentValue.indexOf(option.value);
      if (index > -1) {
        currentValue.splice(index, 1);
      } else {
        currentValue.push(option.value);
      }
      emit("update:modelValue", currentValue);
      emit("change", currentValue);
    } else {
      emit("update:modelValue", option.value);
      emit("change", option.value);
      state.expanded = false;
    }

    // 清空输入框（如果是 filterable）
    if (props.value.filterable && !props.value.multiple) {
      state.inputValue = "";
    }
  };

  // 监听 modelValue 变化
  watch(
    () => props.value.modelValue,
    () => {
      setSelected();
    },
    { deep: true }
  );

  // 监听 options 变化（从 props 创建选项）
  watch(
    () => props.value.options,
    (newOptions) => {
      if (newOptions && newOptions.length > 0) {
        newOptions.forEach((opt) => {
          if (!state.cachedOptions.has(opt.value)) {
            const option: SelectOptionProxy = {
              value: opt.value,
              label: opt.label,
              currentLabel: opt.label,
              disabled: opt.disabled || false,
              visible: true,
              hover: false,
              itemSelected: false,
              isDisabled: opt.disabled || false,
              selectOptionClick: () => {},
            };
            onOptionCreate(option);
          }
        });
      }
      setSelected();
    },
    { immediate: true, deep: true }
  );

  // 监听 expanded 变化
  watch(
    () => state.expanded,
    (expanded) => {
      if (expanded) {
        if (props.value.filterable && filterInputRef.value) {
          nextTick(() => {
            filterInputRef.value?.focus();
          });
        }
      } else {
        state.inputValue = "";
      }
    }
  );

  onMounted(() => {
    setSelected();
  });

  return {
    state,
    selectRef,
    selectTriggerRef,
    selectDropdownRef,
    filterInputRef,
    optionsArray,
    filteredOptions,
    setSelected,
    onOptionCreate,
    onOptionDestroy,
    handleOptionSelect,
  };
}
